/** @noSelf **/

export default class BaseUtil {


    static calculateDamageByPropertySet(unitHandle: unit, dmgPropertySet: {
        strDamageRate?: number,
        agiDamageRate?: number,
        intDamageRate?: number,
        hpDamageRate?: number,
        manaDamageRate?: number,
    }): number {
        let damage = 0;
        if (dmgPropertySet.strDamageRate) {
            damage = GetHeroStr(unitHandle, true) * dmgPropertySet.strDamageRate + damage;
        }
        if (dmgPropertySet.agiDamageRate) {
            damage = GetHeroAgi(unitHandle, true) * dmgPropertySet.agiDamageRate + damage;
        }
        if (dmgPropertySet.intDamageRate) {
            damage = GetHeroInt(unitHandle, true) * dmgPropertySet.intDamageRate + damage;
        }
        if (dmgPropertySet.hpDamageRate) {
            damage = GetUnitState(unitHandle, UNIT_STATE_LIFE) * dmgPropertySet.hpDamageRate + damage;
        }
        if (dmgPropertySet.manaDamageRate) {
            damage = GetUnitState(unitHandle, UNIT_STATE_MANA) * dmgPropertySet.hpDamageRate + damage;
        }
        return damage;
    }


    private static uuid: number = 1

    /**
     * 唯一id
     * 使用时请自行自增一下
     */
    static getUUID(): number {
        BaseUtil.uuid++;
        return BaseUtil.uuid
    }

    /**
     *遍历单位组
     *遍历完后会移除单位组的所有单位
     */
    static SForGroup(whichGroup: group, callback: (unit: unit) => void) {
        for (let i = 0; i <= 1000000; i++) {
            let unitHandle = FirstOfGroup(whichGroup)
            if (!IsHandle(unitHandle)) {
                break
            }
            callback(unitHandle)
            GroupRemoveUnit(whichGroup, unitHandle)
        }
    }

    /**
     *在本地玩家执行
     */
    static forLocalPlayer(fun: () => void, runPlayer = GetTriggerPlayer()) {
        if (runPlayer == GetLocalPlayer()) {
            let old = isAsync
            isAsync = true;
            fun();
            isAsync = old;
        }
    }

    /**
     *中心计时器执行回调函数
     */
    // callBack 返回true 代表继续执行 返回false 代表不再执行
    //count 为执行次数
    static onTimer(timeOut: number, onTimerCall: (count: number) => boolean) {
        let count = 0;
        let callBack = function (this: void) {
            count++;
            let repeat = onTimerCall(count);
            if (repeat) {
                BaseUtil.runLater(timeOut, callBack)
            }
        }
        BaseUtil.runLater(timeOut, callBack)
    }

    static runLater(timeOut: number, callBack: (this: void) => void, loopCount: number = 1) {
        timeOut = math.floor(timeOut * 1000);
        for (let i = 1; i <= loopCount; i++) {
            let callBackTime = BaseUtil.time + (timeOut * i);
            let callBackArray: ((this: void) => void)[] = BaseUtil.timeCallBack[callBackTime];
            if (callBackArray == null) {
                callBackArray = []
                BaseUtil.timeCallBack[callBackTime] = callBackArray;
            }
            callBackArray.push(callBack)
        }
    }

    /**
     *  基础中心计时器
     */
    static centerTimer: timer = null;
    //毫秒计算
    static time = 0;
    static timeCallBack: { [time: number]: ((this: void) => void)[] } = {};

    private static OnTime(this: void) {
        BaseUtil.time = BaseUtil.time + 10;
        let callBackArray = BaseUtil.timeCallBack[BaseUtil.time];
        if (callBackArray) {
            for (let callBackArrayElement of callBackArray) {
                callBackArrayElement();
            }
            BaseUtil.timeCallBack[BaseUtil.time] = null;
        }
    }

    //返回秒
    static getGameTime(): number {
        return BaseUtil.time / 1000;
    }

    static init() {
        BaseUtil.centerTimer = CreateTimer();
        TimerStart(BaseUtil.centerTimer, 0.01, true, BaseUtil.OnTime);
    }

}

